#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2019/1/19 15:04
# @Author  : Seven
# @File    : 5-cornerDemo.py
# @Software: PyCharm
# function :  使用棋盘格及自选风景图像，分别使用Harris、SIFT、FAST及ORB算子检测角点，并比较分析检测结果。
import cv2
import numpy as np
import time


def harrisDemo(img, name):
    """
    harris 角点检测算子
    :param name:
    :param img:
    :return:
    """
    image1 = img.copy()
    grayImage = np.float32(cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY))
    # 输入图像必须是float32，最后一个参数在0.04 到0.05 之间
    # harris角点检测
    harrisImg = cv2.cornerHarris(grayImage, 2, 3, 0.04)
    # 膨胀
    dst = cv2.dilate(harrisImg, None)
    # 对角点图像进行阈值化
    ret, dst = cv2.threshold(dst, 0.01 * dst.max(), 255, 0)
    # 转换为8位图像
    dst = np.uint8(dst)
    # 获取质心坐标-centroids 是每个域的质心坐标
    ret, labels, stats, centroids = cv2.connectedComponentsWithStats(dst)

    criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.001)
    #  计算得出角点坐标
    corners = cv2.cornerSubPix(grayImage, np.float32(centroids), (5, 5), (-1, -1), criteria)
    print('harris-key_points:%s' % name, len(corners))
    # 对所有角点用0圈出来
    for point in corners:
        cv2.circle(image1, tuple(point), 5, (0, 0, 255), 2)
    cv2.imshow('harris-%s' % name, image1)


def surfDemo(img, name):
    """
    SURF 角点检测算子
    :param name:
    :param img:
    :return:
    """
    image2 = img.copy()
    # 特征点检测和提取特征点描述子
    surf = cv2.xfeatures2d.SURF_create()
    key_points = surf.detect(image2, None)
    print('SURF-key_points:%s' % name, len(key_points))
    surfImage = cv2.drawKeypoints(image2, key_points, image2, (0, 0, 255))
    cv2.imshow('SURF-%s' % name, surfImage)


def siftDemo(img, name):
    """
    SIFT 角点检测算子
    :param img:
    :param name:
    :return:
    """
    image2 = img.copy()
    # 特征点检测和提取特征点描述子
    surf = cv2.xfeatures2d.SIFT_create()
    key_points = surf.detect(image2, None)
    print('SIFT-key_points:%s' % name, len(key_points))
    surfImage = cv2.drawKeypoints(image2, key_points, image2, (0, 0, 255))
    cv2.imshow('SIFT-%s' % name, surfImage)


def fastDemo(img, name):
    """
    FAST角点检测算子
    :param name:
    :param img:
    :return:
    """
    image3 = img.copy()
    fast = cv2.FastFeatureDetector.create()
    key_points = fast.detect(image3, None)
    print('FAST-key_points:%s' % name, len(key_points))
    fastImage = cv2.drawKeypoints(image3, key_points, image3, color=(0, 0, 255))
    cv2.imshow('FAST-%s' % name, fastImage)


def orbDemo(img, name):
    """
    ORB检测算子
    :param name:
    :param img:
    :return:
    """
    image4 = img.copy()
    # 特征点检测和提取特征点描述子
    orb = cv2.ORB_create()
    key_points = orb.detect(image4, None)
    print('ORB-key_points:%s' % name, len(key_points))
    surfImage = cv2.drawKeypoints(image4, key_points, image4, (0, 0, 255))
    cv2.imshow('ORB-%s' % name, surfImage)


if __name__ == '__main__':

    # 加载棋盘格图片
    image = cv2.imread('image/chess.png')
    house = cv2.imread('image/house.png')
    house = cv2.pyrDown(house)
    image = cv2.pyrDown(image)
    cv2.imshow('chess', image)
    cv2.imshow('house', house)
    # harris角点检测
    start = time.time()
    harrisDemo(image, 'chess')
    harrisDemo(house, 'house')
    end = time.time()
    print("harris time", start-end)
    # SIFT角点检测
    start = time.time()
    siftDemo(image, 'chess')
    siftDemo(house, 'house')
    end = time.time()
    print("SIFT time", start - end)
    # SURF角点检测
    start = time.time()
    surfDemo(image, 'chess')
    surfDemo(house, 'house')
    end = time.time()
    print("SURF time", start - end)
    # FAST角点检测
    start = time.time()
    fastDemo(image, 'chess')
    fastDemo(house, 'house')
    end = time.time()
    print("FAST time", start - end)
    # ORB角点检测
    start = time.time()
    orbDemo(image, 'chess')
    orbDemo(house, 'house')
    end = time.time()
    print("ORB time", start - end)
    cv2.waitKey(0)

# FAST特征检测算法的检测速度是最快的。
# 从特征点检测效率以及检测出的特征点数来看，SURF表现也不错。
# 检测效率最高的前3个检测器分别为FAST，ORB，SURF
# 综合比较，orb是最好的。
